package com.ruoyi.project.module.propertyConstraint.processor.scan;

import com.google.common.collect.Maps;
import com.ruoyi.project.module.propertyConstraint.processor.model.PropConstraintVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Primary;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.core.annotation.AnnotationUtils;

import java.util.*;

/**
 * com.ruoyi.project.module.propertyConstraint.processor.scan.PropConstraintScan <br>
 *
 * @author 蒋カイセキ    Japan-Tokyo  2018-11-12 22:52:36<br>
 * ブログ http://shoukaiseki.blog.163.com/<br>
 * E-メール jiang28555@Gmail.com<br>
 **/
public class PropConstraintScan  implements ApplicationListener<ContextRefreshedEvent> {

    private final static Logger logger = LoggerFactory.getLogger(PropConstraintScan.class);

    private static Map<String, PropConstraintVO> propConstraintMap = Maps.newHashMap();

    private static PropConstraintVO defaultPropConstraint=null;

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        Map<String,PropConstraintVO> mapTemp = Maps.newHashMap();
        if(event.getApplicationContext().getParent() == null)
        {
            Map<String, Object> beans = event.getApplicationContext().getBeansWithAnnotation(PropConstraint.class);//获取全部ControllerBean
            Set<Map.Entry<String, Object>> entries = beans.entrySet();//遍历Bean
            Iterator<Map.Entry<String, Object>> iterator = entries.iterator();
            while(iterator.hasNext()){
                Map.Entry<String, Object> map = iterator.next();
                logger.info("--------------bean="+map.getKey());
                Class<?> aClass = map.getValue().getClass();
                PropConstraint annotation ;

                //不支持 PropConstraint 中的AliasFor注解
//                annotation = aClass.getAnnotation(PropConstraint.class);
                //支持 PropConstraint 中的AliasFor注解
                annotation=AnnotationUtils.findAnnotation(aClass,PropConstraint.class);
//                PropConstraint cc = AnnotationUtils.findAnnotation(getClass(),PropConstraint.class);

//                StringUtils.arrayToCommaDelimitedString(annotation.value());
                PropConstraintVO pcVO=new PropConstraintVO();

                String value = annotation.value();
                String name = annotation.name();
                String description = annotation.description();
                String remark = annotation.remark();
                pcVO.setValue(value);
                pcVO.setName(name);
                pcVO.setDescription(description);
                pcVO.setRemark(remark);
                pcVO.setClassName(aClass.getName());
                logger.info("value={},name={},description={},remark={}",value,name,description,remark);

                if(AnnotationUtils.findAnnotation(aClass, Primary.class)!=null){
                   if(defaultPropConstraint==null){
                       defaultPropConstraint=pcVO;
                   }else{
                       String errorMsg = String.format("PropConstraint只能有一个Primary注解,冲突的Bean:%s,%s", defaultPropConstraint.getClassName(), pcVO.getClassName());
                       throw new RuntimeException(errorMsg);
                   }
                }

                mapTemp.put(name,pcVO);
            }
//            propConstraintMap = Arrays.<PropConstraint>asList( propConstraintMap.(new PropConstraint[0]));
            propConstraintMap=Collections.unmodifiableMap(mapTemp);
        }
    }

    public Map<String,PropConstraintVO> getPropConstraints(){
       return propConstraintMap;
    }

    public PropConstraintVO getDefaultPropConstraint() {
        return defaultPropConstraint;
    }

}
